package cn.donting.jme.editor.scene;

import cn.donting.jme.EditorContent;
import com.jme3.export.*;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.Camera;
import lombok.Getter;
import lombok.Setter;

import java.io.IOException;

@Getter
public class SceneCamera implements Savable {

    private Camera camera;
    @Setter
    private ColorRGBA viewPortBackColor;
    @Setter
    private boolean viewPortClearDepth=true;
    @Setter
    private boolean viewPortClearColor=true;
    @Setter
    private boolean viewPortClearStencil=true;
    @Setter
    private boolean viewPortEnabled=true;
    @Setter
    private CameraPos cameraPos=CameraPos.Main;

    private float fovY=45f;
    private float near=1f;
    private float far=1000f;
    /**
     * 是否主相机
     * 一个 Scene 必须包含一个主相机
     */
    private boolean mainCamera=true;

    @Override
    public void write(JmeExporter ex) throws IOException {
        OutputCapsule capsule = ex.getCapsule(this);
        capsule.write(camera, "camera", null);
        capsule.write(viewPortBackColor, "viewPortBackColor", ColorRGBA.Black);
        capsule.write(viewPortClearDepth, "viewPortClearDepth", true);
        capsule.write(viewPortClearColor, "viewPortClearStencil", true);
        capsule.write(viewPortClearStencil, "viewPortClearStencil", true);
        capsule.write(viewPortEnabled, "viewPortEnabled", true);
        capsule.write(cameraPos, "cameraPos", CameraPos.Main);
        capsule.write(fovY, "fovY", 45f);
        capsule.write(near, "near", 1f);
        capsule.write(far, "near", 1000f);
    }

    private void updateCameraFrustumPerspective(){
        camera.setFrustumPerspective(fovY, (float) camera.getWidth() / camera.getHeight(), near, far);
    }
    @Override
    public void read(JmeImporter im) throws IOException {
        InputCapsule capsule = im.getCapsule(this);
        camera = (Camera) capsule.readSavable("camera", null);
        viewPortBackColor = (ColorRGBA) capsule.readSavable("viewPortBackColor",  ColorRGBA.Black);
        viewPortClearDepth = capsule.readBoolean("viewPortClearDepth", true);
        viewPortClearColor = capsule.readBoolean("viewPortClearColor", true);
        viewPortClearStencil = capsule.readBoolean("viewPortClearStencil", true);
        viewPortEnabled = capsule.readBoolean("viewPortEnabled", true);
        cameraPos = capsule.readEnum("cameraPos", CameraPos.class, CameraPos.Main);
        fovY = capsule.readFloat("fovY", 45f);
        near = capsule.readFloat("near", 1f);
        far = capsule.readFloat("near", 1000f);
    }

    public void setFar(float far) {
        this.far = far;
        updateCameraFrustumPerspective();
    }

    public void setFovY(float fovY) {
        this.fovY = fovY;
        updateCameraFrustumPerspective();
    }

    public void setNear(float near) {
        this.near = near;
        updateCameraFrustumPerspective();
    }



    public static SceneCamera newInstance(String name, CameraPos cameraPos, boolean isMain) {
        SceneCamera sceneCamera = new SceneCamera();
        sceneCamera.setCameraPos(cameraPos);
        Camera camera = new Camera(EditorContent.getJmeApplication().getEditorCamera().getWidth(), EditorContent.getJmeApplication().getEditorCamera().getHeight());
        camera.setName(name);
        sceneCamera.camera=camera;
        sceneCamera.updateCameraFrustumPerspective();
        sceneCamera.viewPortClearColor = true;
        sceneCamera.viewPortClearDepth = true;
        sceneCamera.viewPortClearStencil = true;
        sceneCamera.viewPortEnabled = true;
        sceneCamera.mainCamera = isMain;
        return sceneCamera;
    }

    public static enum CameraPos {
        Pre,
        Main,
        Post
    }
}
